package working;

// import Hardware.Interrupt;
// import java.util.ArrayList;

public class OS implements OperatingSystem {
	private Hardware simHW;
	private DiskEntity dEnt;
	
	public OS(Hardware hw) {
		simHW = hw; // Set simulator hardware.
		dEnt = new DiskEntity();		
	}

	@Override
	public void interrupt(Hardware.Interrupt it) {
		switch (it) {
		case illegalInstruction:
			break;
		case reboot:
			// Load the disk to primary store.
			simHW.store(Hardware.Address.diskBlockRegister, 0);
			simHW.store(Hardware.Address.diskAddressRegister,
					Hardware.Address.userBase);
			simHW.store(Hardware.Address.diskCommandRegister,
					Hardware.Disk.readCommand);
			printDiskStatusRegister();			
			break;
			
		case systemCall:
			System.out.println("Interrupt: systemCall");
			operatingSystemCall(simHW.fetch(it.ordinal()));
			break;
		case invalidAddress:
			System.out.println("Interrupt: invalidAddress");
			break;
		case disk:
			System.out.println("Interrupt: disk");
//			int ubAddr = Hardware.Address.userBase;	// Start address of the disk.  One dim array...
//			int count = 0;
//			int i;
//			int index = 0;
//			int wData = 0;
//			WordEntity wEnt;
//			BlockEntity bEnt = new BlockEntity();			
//			for (i = Hardware.Address.userBase; i < Hardware.Address.userTop; i++) // Total number of Words.
//			{				
//				wEnt = new WordEntity();	
//				wData = simHW.fetch(ubAddr + index);
//				wEnt.getWordEntityList().add(wData); 
//				System.out.println("Data @(" + (ubAddr + index) + "): " + wData + ", Index: " + count++);
//				bEnt.getWordEntityList().add(wEnt);					
//				index++;
//			}			
//			
//			if(simHW.fetch(Hardware.Address.userBase) == 0 ) //If disk is empty then halt OS
//			{
//				simHW.store(Hardware.Address.haltRegister, 2);
//				System.out.println("Halting the system...");
//			}
//			
////			simHW.fetch(Hardware.Address.userBase);
////			simHW.store(Hardware.Address.systemBase + Hardware.Address.registerSetSize, Hardware.Address.userBase);
			
			simHW.store(Hardware.Address.baseRegister, Hardware.Address.userBase + Hardware.Disk.blockSize);
			simHW.store(Hardware.Address.topRegister, Hardware.Address.userBase + 10);
			
			printDiskStatusRegister();
			break;
		case countdown:
			System.out.println("Interrupt: countdown");
			break;
		}
	}

	public void operatingSystemCall(int sysCall) {
		switch (sysCall) {
		case SystemCall.exec:
			System.out.println("operatingSystemCall: exec");
			break;
		case SystemCall.exit:
			System.out.println("operatingSystemCall: exit");
			break;
		case SystemCall.getSlot:
			System.out.println("operatingSystemCall: getSlot");
			break;
		case SystemCall.putSlot:
			System.out.println("operatingSystemCall: putSlot");
			break;
		case SystemCall.yield:
			System.out.println("operatingSystemCall: yield");
			break;
		}
	}

	/**
	 * prints out the value in diskStatusRegister.
	 */
	public void printDiskStatusRegister() {
		int status = simHW.fetch(Hardware.Address.diskStatusRegister);
		switch (status) {
		case Hardware.Status.ok:
			System.out.println("Hardware.Status.ok");
			break;
		case Hardware.Status.badCommand:
			System.out.println("Hardware.Status.badCommand");
			break;
		case Hardware.Status.badBlockNumber:
			System.out.println("Hardware.Status.ok");
			break;
		case Hardware.Status.badAddress:
			System.out.println("Hardware.Status.badCommand");
			break;
		}
	}
	
	public void printWordValue(int word) {
		System.out.print(Integer.toBinaryString(word) + "\n");
	}

}